﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management;
using System.Text;
using WMI.NET.Abstracts;
using WMI.NET.CIM;

namespace WMI.NET.ComputerSystemHardware.MotherboardControllerPort
{
    /// <summary>
    /// The Win32_SerialPort WMI class represents a serial port on a computer system running Windows.
    /// </summary>
    public class Win32_SerialPort : CIM_SerialController
    {

        private Nullable<Boolean> _Binary;
        private Nullable<UInt32> _MaximumInputBufferSize;
        private Nullable<UInt32> _MaximumOutputBufferSize;
        private Nullable<Boolean> _OSAutoDiscovered;
        private string _ProviderType;
        private Nullable<Boolean> _SettableBaudRate;
        private Nullable<Boolean> _SettableDataBits;
        private Nullable<Boolean> _SettableFlowControl;
        private Nullable<Boolean> _SettableParity;
        private Nullable<Boolean> _SettableParityCheck;
        private Nullable<Boolean> _SettableRLSD;
        private Nullable<Boolean> _SettableStopBits;
        private Nullable<Boolean> _Supports16BitMode;
        private Nullable<Boolean> _SupportsDTRDSR;
        private Nullable<Boolean> _SupportsElapsedTimeouts;
        private Nullable<Boolean> _SupportsIntTimeouts;
        private Nullable<Boolean> _SupportsParityCheck;
        private Nullable<Boolean> _SupportsRLSD;
        private Nullable<Boolean> _SupportsRTSCTS;
        private Nullable<Boolean> _SupportsSpecialCharacters;
        private Nullable<Boolean> _SupportsXOnXOff;
        private Nullable<Boolean> _SupportsXOnXOffSet;

        /// <summary>
        /// If TRUE, the serial port is configured for binary data transfer. Because the Windows API does not support nonbinary mode transfers, this property must be TRUE.
        /// </summary>
        public Nullable<Boolean> Binary { get { return _Binary; } }

        /// <summary>
        /// Maximum size of the serial port driver's internal input buffer. A value of 0 (zero) indicates that no maximum value is imposed by the serial provider.
        /// </summary>
        public Nullable<UInt32> MaximumInputBufferSize { get { return _MaximumInputBufferSize; } }

        /// <summary>
        /// Maximum size of the serial port driver's internal output buffer. A value of 0 (zero) indicates that no maximum value is imposed by the serial provider.
        /// </summary>
        public Nullable<UInt32> MaximumOutputBufferSize { get { return _MaximumOutputBufferSize; } }

        /// <summary>
        /// If TRUE, the instances of this class were automatically discovered by the operating system. If, for example, hardware was added through Control Panel, the operating system finds instances of this class by querying hardware from the instances of this class.
        /// </summary>
        public Nullable<Boolean> OSAutoDiscovered { get { return _OSAutoDiscovered; } }

        /// <summary>
        /// Communications provider type. 
        /// </summary>
        public string ProviderType { get { return _ProviderType; } } //TODO enum

        /// <summary>
        /// If TRUE, the baud rate can be changed for this serial port.
        /// </summary>
        public Nullable<Boolean> SettableBaudRate { get { return _SettableBaudRate; } }

        /// <summary>
        /// If TRUE, data bits can be set for this serial port.
        /// </summary>
        public Nullable<Boolean> SettableDataBits { get { return _SettableDataBits; } }

        /// <summary>
        /// If TRUE, flow control can be set for this serial port.
        /// </summary>
        public Nullable<Boolean> SettableFlowControl { get { return _SettableFlowControl; } }

        /// <summary>
        /// If TRUE, parity can be set for this serial port.
        /// </summary>
        public Nullable<Boolean> SettableParity { get { return _SettableParity; } }

        /// <summary>
        /// If TRUE, parity checking can be set for this serial port (if parity checking is supported).
        /// </summary>
        public Nullable<Boolean> SettableParityCheck { get { return _SettableParityCheck; } }

        /// <summary>
        /// If TRUE, Received Line Signal Detect (RLSD) can be set for this serial port (if RLSD is supported).
        /// </summary>
        public Nullable<Boolean> SettableRLSD { get { return _SettableRLSD; } }

        /// <summary>
        /// If TRUE, stop bits can be set for this serial port.
        /// </summary>
        public Nullable<Boolean> SettableStopBits { get { return _SettableStopBits; } }

        /// <summary>
        /// If TRUE, 16-bit mode is supported on this serial port.
        /// </summary>
        public Nullable<Boolean> Supports16BitMode { get { return _Supports16BitMode; } }

        /// <summary>
        /// If TRUE, data terminal ready (DTR) and data set ready (DSR) signals are supported on this serial port.
        /// </summary>
        public Nullable<Boolean> SupportsDTRDSR { get { return _SupportsDTRDSR; } }

        /// <summary>
        /// If TRUE, elapsed time-outs are supported on this serial port. Elapsed timeouts track the total amount of time between data transmissions.
        /// </summary>
        public Nullable<Boolean> SupportsElapsedTimeouts { get { return _SupportsElapsedTimeouts; } }

        /// <summary>
        /// If TRUE, interval time-outs are supported. An interval timeout is the amount of time allowed to elapse between the arrival of each piece of data.
        /// </summary>
        public Nullable<Boolean> SupportsIntTimeouts { get { return _SupportsIntTimeouts; } }

        /// <summary>
        /// If TRUE, parity checking is supported on this serial port.
        /// </summary>
        public Nullable<Boolean> SupportsParityCheck { get { return _SupportsParityCheck; } }

        /// <summary>
        /// If TRUE, Received Line Signal Detect (RLSD) is supported on this serial port.
        /// </summary>
        public Nullable<Boolean> SupportsRLSD { get { return _SupportsRLSD; } }

        /// <summary>
        /// If TRUE, ready to send (RTS) and clear to send (CTS) signals are supported on this serial port.
        /// </summary>
        public Nullable<Boolean> SupportsRTSCTS { get { return _SupportsRTSCTS; } }

        /// <summary>
        /// If TRUE, serial port control characters are supported. These characters signal events rather than data. These characters are not displayable and are set by the driver. They include EofChar, ErrorChar, BreakChar, EventChar, XonChar, and XoffChar.
        /// </summary>
        public Nullable<Boolean> SupportsSpecialCharacters { get { return _SupportsSpecialCharacters; } }

        /// <summary>
        /// If TRUE, XON or XOFF flow-control is supported on this serial port.
        /// </summary>
        public Nullable<Boolean> SupportsXOnXOff { get { return _SupportsXOnXOff; } }

        /// <summary>
        /// If TRUE, the communications provider supports configuration of the XONor XOFF flow-control setting.
        /// </summary>
        public Nullable<Boolean> SupportsXOnXOffSet { get { return _SupportsXOnXOffSet; } }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mbo"></param>
        public Win32_SerialPort(ManagementBaseObject mbo)
            : base(mbo)
        {
            _Binary = mbo.GetBoolValue("Binary");
            _MaximumInputBufferSize = mbo.GetUIntValue("MaximumInputBufferSize");
            _MaximumOutputBufferSize = mbo.GetUIntValue("MaximumOutputBufferSize");
            _OSAutoDiscovered = mbo.GetBoolValue("OSAutoDiscovered");
            _ProviderType = mbo.GetStringValue("ProviderType");
            _SettableBaudRate = mbo.GetBoolValue("SettableBaudRate");
            _SettableDataBits = mbo.GetBoolValue("SettableDataBits");
            _SettableFlowControl = mbo.GetBoolValue("SettableFlowControl");
            _SettableParity = mbo.GetBoolValue("SettableParity");
            _SettableParityCheck = mbo.GetBoolValue("SettableParityCheck");
            _SettableRLSD = mbo.GetBoolValue("SettableRLSD");
            _SettableStopBits = mbo.GetBoolValue("SettableStopBits");
            _Supports16BitMode = mbo.GetBoolValue("Supports16BitMode");
            _SupportsDTRDSR = mbo.GetBoolValue("SupportsDTRDSR");
            _SupportsElapsedTimeouts = mbo.GetBoolValue("SupportsElapsedTimeouts");
            _SupportsIntTimeouts = mbo.GetBoolValue("SupportsIntTimeouts");
            _SupportsParityCheck = mbo.GetBoolValue("SupportsParityCheck");
            _SupportsRLSD = mbo.GetBoolValue("SupportsRLSD");
            _SupportsRTSCTS = mbo.GetBoolValue("SupportsRTSCTS");
            _SupportsSpecialCharacters = mbo.GetBoolValue("SupportsSpecialCharacters");
            _SupportsXOnXOff = mbo.GetBoolValue("SupportsXOnXOff");
            _SupportsXOnXOffSet = mbo.GetBoolValue("SupportsXOnXOffSet");
        }

    }



    /// <summary>
    /// 
    /// </summary>
    public class GetWin32_SerialPorts : Win32Collection<Win32_SerialPort>
    {

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override ReadOnlyCollection<Win32_SerialPort> GetCollection()
        {
            List<Win32_SerialPort> tempCollection = new List<Win32_SerialPort>();

            foreach (var s in searcher.Get())
            {
                Win32_SerialPort tempListItem = new Win32_SerialPort(s);
                tempCollection.Add(tempListItem);
            }

            return tempCollection.AsReadOnly();
        }

        /// <summary>
        /// 
        /// </summary>
        public GetWin32_SerialPorts() : base("SELECT * FROM Win32_SerialPort") { }

    }


}
